﻿namespace JunFan.Tests.RepositoriesTests
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Domain;
    using FluentAssertions;
    using Repositories;
    using Infrastructure;

    [TestClass]
    public class ItemRepositoryTests
    {
        [TestInitialize]
        public void CleanAllItems()
        {
            TestSetup.CleanupDatabase();
        }

        [TestMethod]
        public void CreateItem()
        {
            var itemRepository = new ItemRepository();

            var item = new Item
                {
                    Id = "1", 
                    Description = "a description",
                    CreatedOn = DateTime.Today.AddDays(-10),
                    StartedOn = DateTime.Today.AddDays(-5),
                    CompletedOn = DateTime.Today
                };

            var createdItem = itemRepository.Create(item);

            createdItem.ShouldBeEquivalentTo(item, option => option.Excluding(itm => itm.InternalId));
        }

        [TestMethod]
        public void UpdateItem()
        {
            // Arrange

            var itemRepository = new ItemRepository();

            var item = AnyItem();

            item = itemRepository.Create(item);

            // Act
            itemRepository = new ItemRepository();

            Item itemToUpdate = itemRepository.Read(item.InternalId);

            itemToUpdate.Description = "new description";
            itemToUpdate.Id = itemToUpdate.Id + "_2";
            itemToUpdate.CreatedOn = itemToUpdate.CreatedOn.AddDays(-4);

            itemRepository.Update(itemToUpdate);

            // Assert
            itemRepository = new ItemRepository();
            Item updatedItem = itemRepository.Read(item.InternalId);

            updatedItem.ShouldBeEquivalentTo(itemToUpdate);
        }

        [TestMethod]
        public void ReadAllWithFilter()
        {
            var itemRepository = new ItemRepository();

            IEnumerable<Item> activeItems = Given.NewItem.Build(10).Create(itemRepository);

            Given.CompletedItem.Build(10).Create(itemRepository);

            IEnumerable<Item> resultItems = itemRepository.ReadAll(itm => !itm.CompletedOn.HasValue);

            resultItems.ShouldAllBeEquivalentTo(activeItems, options => options.Excluding(itm => itm.InternalId));
        }

        [TestMethod]
        public void ReadInexistentItem()
        {
            var itemRepository = new ItemRepository();

            var item = itemRepository.Read(31);

            item.Should().BeNull("The repository should return null when reading an inexistent id.");

        }

        private static Item AnyItem()
        {
            return new Item
                {
                    Id = "1", 
                    Description = "a item", 
                    CreatedOn = DateTime.Today.AddDays(-2)
                };
        }
    }
}
